#include "input.h"

// For now, rely on windows
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace Putin{

	InputManager::InputManager()
	{
		// Not sure if we really should init it all just here..
		mRunning = false;
	}

	InputManager::~InputManager()
	{
		if( mRunning ) 
			terminate();
	}

	bool InputManager::init()
	{
		mRunning = true;
		return true;
	}

	bool InputManager::terminate()
	{

		for each( InputFunctorBase* f in mKeyboardCallbacks)
			delete f;
		
		for each( InputFunctorBase* f in mMouseClickCallbacks)
			delete f;

		for each( InputFunctorBase* f in mMouseMoveCallbacks)
			delete f;

		return true;
	}

	bool InputManager::update()
	{
		// Acquire...
		GetKeyboardState(mKeyBuffer);
		POINT p;
		GetCursorPos(&p);
		mMouseX = p.x;
		mMouseY = p.y;

		// Only pass on the first key pressed. (only one at a time supported)
		// for more precision, isKeyDown can be used to check multiple keys
		// this is because the callback is sync. not async.

		for(int i=0;i<256;i++)
		{
			if( mKeyBuffer[i] & 0x80 )
			{
				if( i != VK_LBUTTON && i != VK_RBUTTON && i != VK_MBUTTON)
				{
					for each( InputFunctorBase* f in mKeyboardCallbacks)
					{
						InputArg ia;
						ia.key = i; // windows format VIRTUAL KEY CODES
						//http://msdn.microsoft.com/en-us/library/ms645540%28VS.85%29.aspx

						ia.x = mMouseX;
						ia.y = mMouseY;
						(*f)(ia);
					}
				}
				else
				{
					for each( InputFunctorBase* f in mMouseClickCallbacks)
					{
						InputArg ia;
						ia.key = i; // windows format VIRTUAL KEY CODES
						//http://msdn.microsoft.com/en-us/library/ms645540%28VS.85%29.aspx

						ia.x = mMouseX;
						ia.y = mMouseY;
						(*f)(ia);
					}
				}
			}
		}

		// Pass on the mouse move callbacks
		for each( InputFunctorBase* f in mMouseMoveCallbacks)
		{
			InputArg ia;
			ia.key = 0; // Not used

			ia.x = mMouseX;
			ia.y = mMouseY;
			(*f)(ia);
		}

		return true;
	}

	Vec2i InputManager::getMousePos()
	{
		Vec2i m;
		m.x = mMouseX;
		m.y = mMouseY;
		return m;
	}

	bool InputManager::isKeyDown(unsigned char key)
	{
		return (mKeyBuffer[key] & 0x80) != 0; // work with caps/scroll/num lock keys also
	}

	void InputManager::addKeyboardCallback(InputFunctorBase *func)
	{
		mKeyboardCallbacks.push_back(func);
	}

	void InputManager::addMouseClickCallback(InputFunctorBase *func)
	{
		mMouseClickCallbacks.push_back(func);
	}

	void InputManager::addMouseMoveCallback(InputFunctorBase *func)
	{
		mMouseMoveCallbacks.push_back(func);
	}
}


